home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / WFC010.ZIP / SRC / CSQUIGL.CPP < prev    next >
C/C++ Source or Header  |  1995-12-07  |  10KB  |  426 lines

  1. #include <wfc.h>
  2. #pragma hdrstop
  3.  
  4. /*
  5. ** Author: Samuel R. Blackburn
  6. ** CI$: 76300,326
  7. ** Internet: sammy@sed.csc.com
  8. **
  9. ** You can use it any way you like as long as you don't try to sell it.
  10. **
  11. ** Any attempt to sell WFC in source code form must have the permission
  12. ** of the original author. You can produce commercial executables with
  13. ** WFC but you can't sell WFC.
  14. **
  15. ** Copyright, 1995, Samuel R. Blackburn
  16. **
  17. ** $Workfile: $
  18. ** $Revision: $
  19. ** $Modtime: $
  20. */
  21.  
  22. #if defined( _DEBUG )
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. IMPLEMENT_SERIAL( CSquiggleData, CObject, 1 )
  28. IMPLEMENT_SERIAL( CSquiggle, CRectangle, 1 )
  29.  
  30. #if defined( _DEBUG )
  31. #define new DEBUG_NEW
  32. #endif
  33.  
  34. /*
  35. ** The data that will be squiggle-ized...
  36. */
  37.  
  38. CSquiggleData::CSquiggleData()
  39. {
  40.    m_Initialize();
  41. }
  42.  
  43. CSquiggleData::~CSquiggleData()
  44. {
  45.    m_Initialize();
  46. }
  47.  
  48. void CSquiggleData::Copy( const CSquiggleData *source_p )
  49. {
  50.    if ( source_p == (CSquiggleData *) NULL )
  51.    {
  52.       m_Initialize();
  53.       return;
  54.    }
  55.  
  56.    Start        = source_p->Start;
  57.    Stop         = source_p->Stop;
  58.    Time         = source_p->Time;
  59.    MinimumValue = source_p->MinimumValue;
  60.    MaximumValue = source_p->MaximumValue;
  61.  
  62.    /*
  63.    ** MFC doesn't provide an equals (assignment) operator for their CWordArray class. Odd, they provide one for
  64.    ** CString... Anyway, we've got to write a bunch of code that should have already been written
  65.    */
  66.  
  67.    Data.RemoveAll();
  68.    
  69.    int number_of_elements = source_p->Data.GetSize();
  70.    int index              = 0;
  71.    
  72.    Data.SetSize( number_of_elements );
  73.  
  74.    while( index < number_of_elements )
  75.    {
  76.       Data.Add( source_p->Data.GetAt( index ) );
  77.       index++;
  78.    }
  79. }
  80.  
  81. void CSquiggleData::Empty( void )
  82. {
  83.    m_Initialize();
  84. }
  85.  
  86. void CSquiggleData::m_Initialize( void )
  87. {
  88.    Start.Empty();
  89.    Stop.Empty();
  90.    Time = CTime( 0 );
  91.    MinimumValue = 0;
  92.    MaximumValue = 0;
  93.    Data.RemoveAll();
  94. }
  95.  
  96. void CSquiggleData::Serialize( CArchive& archive )
  97. {
  98.    CObject::Serialize( archive );
  99.  
  100.    if ( archive.IsStoring() )
  101.    {
  102.       archive << Start;
  103.       archive << Stop;
  104.       archive << Time;
  105.       archive << MinimumValue;
  106.       archive << MaximumValue;
  107.    }
  108.    else
  109.    {
  110.       archive >> Start;
  111.       archive >> Stop;
  112.       archive >> Time;
  113.       archive >> MinimumValue;
  114.       archive >> MaximumValue;
  115.    }
  116.  
  117.    Data.Serialize( archive );
  118. }
  119.  
  120. WORD CSquiggleData::ValidRange( void )
  121. {
  122.    if ( MinimumValue > MaximumValue )
  123.    {
  124.       WORD temp_word = MaximumValue;
  125.       MaximumValue = MinimumValue;
  126.       MinimumValue = temp_word;
  127.    }
  128.  
  129.    return( (WORD) ( MaximumValue - MinimumValue ) );
  130. }
  131.  
  132. /*
  133. ** The Squiggle that you see on the screen
  134. */
  135.  
  136. CSquiggle::CSquiggle()
  137. {
  138.    m_Automatically_Delete = FALSE;
  139.    m_PointArray           = (POINT *) NULL;
  140.    m_Initialize();
  141. }
  142.  
  143. CSquiggle::CSquiggle( DWORD height, DWORD width, const CPoint& location, COLORREF fill_color, COLORREF line_color )
  144.           :CRectangle( height, width, location, fill_color, line_color )
  145. {
  146.    m_Automatically_Delete = FALSE;
  147.    m_PointArray           = (POINT *) NULL;
  148.    m_Initialize();
  149. }
  150.  
  151. CSquiggle::~CSquiggle()
  152. {
  153.    if ( m_PointArray != (POINT *) NULL )
  154.    {
  155.       delete [] m_PointArray;
  156.       m_PointArray = (POINT *) NULL;
  157.    }
  158.  
  159.    if ( m_Automatically_Delete == TRUE )
  160.    {
  161.       delete m_Squiggle_Data_p;
  162.    }
  163.  
  164.    m_Initialize();
  165. }
  166.  
  167. void CSquiggle::Copy( const CSquiggle *source_p )
  168. {
  169.    m_Initialize();
  170.  
  171.    CSquiggleData *data_p = new CSquiggleData;
  172.  
  173.    data_p->Copy( source_p->m_Squiggle_Data_p );
  174.  
  175.    SetSquiggleData( data_p, TRUE );
  176.  
  177.    CRectangle::Copy( source_p );
  178. }
  179.  
  180. void CSquiggle::Draw( CDC& device_context )
  181. {
  182.    if ( m_Squiggle_Data_p == (CSquiggleData *) NULL )
  183.    {
  184.       return;
  185.    }
  186.  
  187.    CBitmap bitmap;
  188.  
  189.    CDC temporary_device_context;
  190.  
  191.    CBrush brush( m_FillColor );
  192.  
  193.    DWORD width  = GetWidth();
  194.    DWORD height = GetHeight();
  195.  
  196.    BOOL result = bitmap.CreateCompatibleBitmap( &device_context, (int) width, (int) height );
  197.  
  198.    if ( result == 0 )
  199.    {
  200.       return;
  201.    }
  202.  
  203.    result = temporary_device_context.CreateCompatibleDC( &device_context );
  204.  
  205.    if ( result == 0 )
  206.    {
  207.       return;
  208.    }
  209.  
  210.    CBitmap *original_bitmap = temporary_device_context.SelectObject( &bitmap );
  211.  
  212.    temporary_device_context.FillRect( CRect( 0, 0, (int) width, (int) height ), &brush );
  213.  
  214.    /*
  215.    ** Draw the grid if we need to
  216.    */
  217.  
  218.    if ( m_NumberOfXGridLines > 0 || m_NumberOfYGridLines > 0 )
  219.    {
  220.       CPen grid_line_pen( (int) m_GridLineType, 1, m_GridLineColor );
  221.  
  222.       CPen *original_pen = temporary_device_context.SelectObject( &grid_line_pen );
  223.  
  224.       /*
  225.       ** Now turn the background color into the same color as our FillRect to prevent
  226.       ** dotted pens from being color-white-color...
  227.       */
  228.  
  229.       COLORREF original_background_color = temporary_device_context.SetBkColor( m_FillColor );
  230.  
  231.       int index = 0;
  232.  
  233.       for( index = 1; index < m_NumberOfXGridLines; index++ )
  234.       {
  235.          temporary_device_context.MoveTo( (int) ( index * width / m_NumberOfXGridLines ), 0            );
  236.          temporary_device_context.LineTo( (int) ( index * width / m_NumberOfXGridLines ), (int) height );
  237.       }
  238.  
  239.       for( index = 1; index < m_NumberOfYGridLines; index++ )
  240.       {
  241.          temporary_device_context.MoveTo( 0,           (int) ( index * height / m_NumberOfYGridLines ) );
  242.          temporary_device_context.LineTo( (int) width, (int) ( index * height / m_NumberOfYGridLines ) );
  243.       }
  244.  
  245.       temporary_device_context.SetBkColor( original_background_color );
  246.       temporary_device_context.SelectObject( original_pen );
  247.       grid_line_pen.DeleteObject();
  248.    }
  249.  
  250.    CPen line_pen( PS_SOLID, (int) m_LineThickness, m_LineColor );
  251.  
  252.    CPen *original_pen = temporary_device_context.SelectObject( &line_pen );
  253.  
  254.    temporary_device_context.Polyline( (LPPOINT) m_PointArray, m_NumberOfPoints );
  255.  
  256.    /*
  257.    ** Copy to the screen
  258.    */
  259.  
  260.    device_context.BitBlt( m_Location.x, m_Location.y, (int) width, (int) height, &temporary_device_context, 0, 0, SRCCOPY );
  261.  
  262.    /*
  263.    ** Clean up
  264.    */
  265.  
  266.    temporary_device_context.SelectObject( original_pen    );
  267.    temporary_device_context.SelectObject( original_bitmap );
  268.    line_pen.DeleteObject();
  269.    bitmap.DeleteObject();
  270. }
  271.  
  272. void CSquiggle::Empty( void )
  273. {
  274.    m_Initialize();
  275. }
  276.  
  277. DWORD CSquiggle::GetLineThickness( void ) const
  278. {
  279.    return( m_LineThickness );
  280. }
  281.  
  282. void CSquiggle::m_Initialize( void )
  283. {
  284.    m_Squiggle_Data_p     = (CSquiggleData *) NULL;
  285.    m_PointArray          = (POINT *) NULL;
  286.    m_NumberOfPoints      = 0;
  287.    m_NumberOfXGridLines  = 0;
  288.    m_NumberOfYGridLines  = 0;
  289.    m_GridLineColor       = DARK_GREEN;
  290.    m_LineThickness       = 1;
  291.    m_GridLineType        = PS_DOT;
  292. }
  293.  
  294. void CSquiggle::Serialize( CArchive& archive )
  295. {
  296.    CRectangle::Serialize( archive );
  297.  
  298.    if ( archive.IsStoring() )
  299.    {
  300.       archive << m_NumberOfXGridLines;
  301.       archive << m_NumberOfYGridLines;
  302.       archive << m_GridLineColor;
  303.       archive << m_LineThickness;
  304.       archive << m_GridLineType;
  305.  
  306.       DWORD do_we_have_data = 0;
  307.  
  308.       if ( m_Squiggle_Data_p != (CSquiggleData *) NULL )
  309.       {
  310.          do_we_have_data = 1;
  311.       }
  312.  
  313.       archive << do_we_have_data;
  314.  
  315.       if ( do_we_have_data == 1 )
  316.       {
  317.          m_Squiggle_Data_p->Serialize( archive );
  318.       }
  319.    }
  320.    else
  321.    {
  322.       archive >> m_NumberOfXGridLines;
  323.       archive >> m_NumberOfYGridLines;
  324.       archive >> m_GridLineColor;
  325.       archive >> m_LineThickness;
  326.       archive >> m_GridLineType;
  327.  
  328.       DWORD is_there_data = 0;
  329.  
  330.       archive >> is_there_data;
  331.  
  332.       if ( is_there_data == 1 )
  333.       {
  334.          CSquiggleData *data_p = new CSquiggleData;
  335.  
  336.          data_p->Serialize( archive );
  337.  
  338.          SetSquiggleData( data_p, TRUE );
  339.       }
  340.    }
  341. }
  342.  
  343. void CSquiggle::SetGridLineColor( COLORREF grid_line_color )
  344. {
  345.    m_GridLineColor = grid_line_color;
  346. }
  347.  
  348. void CSquiggle::SetGridLineType( DWORD type )
  349. {
  350.    m_GridLineType = type;
  351. }
  352.  
  353. void CSquiggle::SetLineThickness( DWORD thickness )
  354. {
  355.    m_LineThickness = thickness;
  356. }
  357.  
  358. void CSquiggle::SetNumberOfGridLines( WORD number_of_x_lines, WORD number_of_y_lines )
  359. {
  360.    m_NumberOfXGridLines = number_of_x_lines;
  361.    m_NumberOfYGridLines = number_of_y_lines;
  362. }
  363.  
  364. void CSquiggle::SetSquiggleData( CSquiggleData *source_p, BOOL auto_delete )
  365. {
  366.    if ( m_PointArray != (POINT *) NULL )
  367.    {
  368.       delete [] m_PointArray;
  369.       m_PointArray = (POINT *) NULL;
  370.    }
  371.  
  372.    m_NumberOfPoints = 0;
  373.  
  374.    if ( m_Automatically_Delete == TRUE )
  375.    {
  376.       delete m_Squiggle_Data_p;
  377.       m_Squiggle_Data_p = (CSquiggleData *) NULL;
  378.       m_Automatically_Delete = FALSE;
  379.    }
  380.  
  381.    if ( source_p != (CSquiggleData *) NULL )
  382.    {
  383.       m_Squiggle_Data_p      = source_p;
  384.       m_Automatically_Delete = auto_delete;
  385.  
  386.       m_NumberOfPoints = source_p->Data.GetSize();
  387.  
  388.       m_PointArray = new POINT[ m_NumberOfPoints ];
  389.  
  390.       if ( m_PointArray == (POINT *) NULL )
  391.       {
  392.          /*
  393.          ** Out of Memory
  394.          */
  395.  
  396.          m_NumberOfPoints = 0;
  397.          return;
  398.       }
  399.  
  400.       int number_of_data_points = m_NumberOfPoints;
  401.  
  402.       if ( number_of_data_points == 0 )
  403.       {
  404.          number_of_data_points = 1;
  405.       }
  406.  
  407.       int valid_range = m_Squiggle_Data_p->ValidRange();
  408.  
  409.       if ( valid_range == 0 )
  410.       {
  411.          valid_range = 1;
  412.       }
  413.  
  414.       double x_ratio = (double) GetWidth()  / (double) number_of_data_points;
  415.       double y_ratio = (double) GetHeight() / (double) valid_range;
  416.  
  417.       int origin_y = (int) ( (double) m_Squiggle_Data_p->MaximumValue * y_ratio );
  418.  
  419.       for ( int index = 0; index < m_NumberOfPoints; index++ )
  420.       {
  421.          m_PointArray[ index ].x = (int) ( (double) index * x_ratio );
  422.          m_PointArray[ index ].y = origin_y - (int) ( (double) m_Squiggle_Data_p->Data.GetAt( index ) * y_ratio );
  423.       }
  424.    }
  425. }
  426.